/*
 * @(#)SearchableUtils.java
 *
 * Copyright 2002 - 2004 JIDE Software Inc. All rights reserved.
 */
package com.jidesoft.swing;

import javax.swing.*;
import javax.swing.text.JTextComponent;

/**
 * 功能类用于创建可搜索组件. 使用这个类非常简单. 为了创建组件, 所有你需要做的就是调用 <code><pre>
 * SearchableUtils.installSearchable(component);
 * </pre></code> component 可以是 JList, JTree 或者 JTable. 如果你需要更进一步自定义 Searchable
 * 的一些属性, 你需要分配一个变量用于接收 installSearchable() 的返回. <code><pre>
 * Searchable searchable = SearchableUtils.installSearchable(component);
 * // 进一步配置
 * searchable.setCaseSensitive(true);
 * // ...
 * </pre></code> 通常你不需要从组件卸载 searchable . 但是如果出于某个原因, 你需要停用组件的可搜索功能, 你可以调用
 * uninstallSearchable(). <code><pre>
 * Searchable searchable = SearchableUtils.installSearchable(component);
 * // ...
 * // 卸载它
 * SearchableUtils.uninstallSearchable(searchable);
 * </pre></code>
 * <p/>
 * 有一个小技巧你需要知道. JTree 和 JList 实现了部分快速搜索功能, 因此当你输入首字符, 它将会跳到首次出现的位置.
 * 这个功能优势会和我们提供的 Searchable 冲突. 因此你最好禁用 JTree 或者 JList 默认功能通过创建 JTree 和 JList 重写
 * getNextMatch 方法. 参阅下面 <code><pre>
 * JTree tree = new JTree(...) {
 *     public TreePath getNextMatch(String prefix, int startingRow, Position.Bias bias) {
 *         return null;
 *     }
 * };
 * <p/>
 * JList list = new JList(...){
 *     public int getNextMatch(String prefix, int startIndex, Position.Bias bias) {
 *         return -1;
 *     }
 * };
 * </pre></code>
 */
public class SearchableUtils {
	/**
	 * 安装可搜索功能到 JTree.
	 *
	 * @param tree
	 *            待安装搜索功能的 JTree
	 * @return TreeSearchable
	 */
	public static TreeSearchable installSearchable(JTree tree) {
		return new TreeSearchable(tree);
	}

	/**
	 * 安装可搜索功能到 JTable.
	 *
	 * @param table
	 *            待安装搜索功能的 JTable
	 * @return TableSearchable
	 */
	public static TableSearchable installSearchable(JTable table) {
		return new TableSearchable(table);
	}

	/**
	 * 安装可搜索功能到 JList.
	 *
	 * @param list
	 *            待安装搜索功能的 JList
	 * @return ListSearchable
	 */
	public static ListSearchable installSearchable(JList list) {
		return new ListSearchable(list);
	}

	/**
	 * 安装可搜索功能到 JComboBox.
	 *
	 * @param combobox
	 *            待安装搜索功能的组合框
	 * @return ComboBoxSearchable
	 */
	public static ComboBoxSearchable installSearchable(JComboBox combobox) {
		return new ComboBoxSearchable(combobox);
	}

	/**
	 * 安装可搜索功能到 JTextComponent.
	 *
	 * @param textComponent
	 *            待安装搜索功能的文本组件
	 * @return TextComponentSearchable
	 */
	public static TextComponentSearchable installSearchable(JTextComponent textComponent) {
		return new TextComponentSearchable(textComponent);
	}

	/**
	 * 卸载组件已安装的可搜索功能
	 *
	 * @param searchable
	 *            searchable.
	 */
	public static void uninstallSearchable(Searchable searchable) {
		if (searchable != null) {
			searchable.hidePopup();
			searchable.uninstallListeners();
			if (searchable.getComponent() instanceof JComponent) {
				Object clientProperty = ((JComponent) searchable.getComponent())
						.getClientProperty(Searchable.CLIENT_PROPERTY_SEARCHABLE);
				if (clientProperty == searchable) {
					((JComponent) searchable.getComponent()).putClientProperty(Searchable.CLIENT_PROPERTY_SEARCHABLE,
							null);
				}
			}
		}
	}

	/**
	 * 卸载组件已安装的可搜索功能
	 *
	 * @param component
	 *            已安装可搜索功能的组件.
	 */
	public static void uninstallSearchable(JComponent component) {
		if (component != null) {
			Object clientProperty = component.getClientProperty(Searchable.CLIENT_PROPERTY_SEARCHABLE);
			if (clientProperty instanceof Searchable) {
				Searchable searchable = ((Searchable) clientProperty);
				searchable.hidePopup();
				searchable.uninstallListeners();
				component.putClientProperty(Searchable.CLIENT_PROPERTY_SEARCHABLE, null);
			}
		}
	}
}
